package Docker

import (
	"context"
	"os"
    "strconv"
	"strings"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
	"github.com/olekukonko/tablewriter"
	"fmt"
	"bufio"
	"time"
)

// 列出运行中容器
func Docker_list_container( All,n bool) {
	// 创建Docker客户端
    cli, err := client.NewClientWithOpts(client.FromEnv)
    if err != nil {
        panic(err)
    }
	// 检查Docker客户端是否正常运行
	_, err = cli.Ping(context.Background())
	if err != nil {
		fmt.Println(Red,"Docker未运行,请启动后再执行", Reset)
		time.Sleep(2 * time.Second)
		return
	}
    // 列出所有容器
	var containers []types.Container

	if All == true {
		var err error
		containers, err = cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
		if err != nil {
			panic(err)
		}
	} else {
		var err error
		containers, err = cli.ContainerList(context.Background(), types.ContainerListOptions{})
		if err != nil {
			panic(err)
		}
	}


	//判断是否有容器，没有则返回
	if len(containers) == 0 {
		//黄色
		fmt.Println(Yellow,"没有容器,请使用命令行运行容器", Reset)
		time.Sleep(2 * time.Second)
		return
	}

    // 初始化表格
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"ID", "镜像", "命令", "创建时间", "状态", "端口", "容器名字"})
	// 遍历容器列表，输出表格行
	for _, container := range containers {
		// 获取容器的端口映射情况
		var ports []string
		for _, port := range container.Ports {
			ports = append(ports, strconv.Itoa(int(port.PrivatePort))+"->"+strconv.Itoa(int(port.PublicPort))+"/"+port.Type)
		}
		// 获取容器的创建时间
		createdTime := time.Unix(container.Created, 0).Format("2006-01-02 15:04:05")
		// 获取容器的状态
		var status string
		if container.State == "running" {
			status = container.State 
		} else {
			status = container.State 
		}
		// 获取容器的命令
		var command string
		if len(container.Command) > 20 {
			command = container.Command[:20] + "..."
		} else {
			command = container.Command
		}
		// 获取容器的镜像
		var image string
		if len(container.Image) > 20 {
			image = container.Image[:20] + "..."
		} else {
			image = container.Image
		}
		// 获取容器的名字
		var name string
		if len(container.Names[0]) > 20 {
			name = container.Names[0][1:20] + "..."
		} else {
			name = container.Names[0][1:]
		}
		table.Append([]string{
			container.ID[:12],
			image,
			command,
			createdTime,
			status,
			strings.Join(ports, ","),
			name,
		})
	}
	// 输出表格
    // 输出表格
	
    table.Render()
	if n == true {
		fmt.Printf("按回车键继续...")
		fmt.Scanln()
	}

}


// 列出所有镜像,删除
func Docker_list_image(del,n bool) {
	cli, err := client.NewClientWithOpts(client.FromEnv)
    if err != nil {
        panic(err)
    }

    // 检查Docker客户端是否正常运行
    _, err = cli.Ping(context.Background())
    if err != nil {
        fmt.Println(Red,"Docker未运行,请启动后再执行", Reset)
		time.Sleep(2 * time.Second)
        return
    }

    // 列出所有镜像
    images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
    if err != nil {
        panic(err)
    }
	//判断是否有镜像，没有则返回
	if len(images) == 0 {
		fmt.Println(Yellow,"没有镜像,请使用命令行运行下载命令", Reset)
		time.Sleep(2 * time.Second)
		return
	}

    // 初始化表格
    table := tablewriter.NewWriter(os.Stdout)
    table.SetHeader([]string{"ID", "仓库", "标签", "大小"})

    // 遍历镜像列表，输出表格行
    for _, image := range images {
        for _, repoTag := range image.RepoTags {
            split := strings.Split(repoTag, ":")
            // 如果镜像没有tag，则将tag设置为"latest"
            if len(split) < 2 {
                split = append(split, "latest")
            }
            table.Append([]string{
                image.ID[7:],
                split[0],
                split[1],
                strconv.FormatInt(image.Size, 10),
            })
        }
    }

    // 输出表格
    table.Render()

	if del == true {
		// 从标准输入中获取要删除的镜像ID
		reader := bufio.NewReader(os.Stdin)
		fmt.Print("请输入要删除的镜像ID(CTRL+C中断): ")
		imageID, _ := reader.ReadString('\n')
		imageID = strings.TrimSpace(imageID)

		// 删除镜像
		_, err = cli.ImageRemove(context.Background(), imageID, types.ImageRemoveOptions{})
		if err != nil {
			// 红色字体
			fmt.Println(Red,"删除镜像失败,可能镜像被占用,请检查容器是否再使用...",Reset)
			time.Sleep(2 * time.Second)
			return
		}
		time.Sleep(2 * time.Second)
		//判断是否删除
		_, err = cli.ImageList(context.Background(), types.ImageListOptions{})
		if err != nil {
			//绿色字体
			fmt.Println(Green,"删除镜像成功", Reset)
			time.Sleep(2 * time.Second)
			return
		}
	}
	//按任意键继续
	if n == true {
		fmt.Printf("按回车键继续...")
		fmt.Scanln()
	}
}